"""
ConnLLM适配层模式定义
定义配置和消息的标准模式和验证函数
"""
from typing import Dict, Any, List, Optional, Type, Union, Callable

from .exceptions import ConfigurationError


# 基础配置模式
BASE_CONFIG_SCHEMA = {
	"provider": {
		"type": str,
		"required": True,
		"description": "提供商类型，如'anthropic'、'openai'等"
	},
	"model": {
		"type": str,
		"required": True,
		"description": "模型名称，如'claude-3-5-sonnet'、'gpt-4o'等"
	},
	"temperature": {
		"type": float,
		"required": False,
		"default": 0.1,
		"description": "生成多样性，0-1之间，越高结果越多样"
	},
	"max_tokens": {
		"type": int,
		"required": False,
		"default": 4096,
		"description": "生成的最大token数"
	},
	"max_retries": {
		"type": int,
		"required": False,
		"default": 3,
		"description": "API调用失败时的最大重试次数"
	},
	"retry_delay": {
		"type": float,
		"required": False,
		"default": 1.0,
		"description": "重试间隔时间(秒)"
	},
	"timeout": {
		"type": float,
		"required": False,
		"default": 60.0,
		"description": "API调用超时时间(秒)"
	}
}

# 远程提供商配置扩展
REMOTE_CONFIG_SCHEMA = {
	"api_key": {
		"type": str,
		"required": True,
		"description": "API密钥"
	},
	"api_base": {
		"type": str,
		"required": False,
		"description": "API基础URL，可以用于自定义或私有部署"
	},
	"proxy": {
		"type": str,
		"required": False,
		"default": None,
		"description": "代理设置，如'http://127.0.0.1:7890'"
	}
}

# 本地提供商配置扩展
LOCAL_CONFIG_SCHEMA = {
	"host": {
		"type": str,
		"required": False,
		"default": "http://localhost:11434",
		"description": "本地服务主机地址"
	}
}

# 特定提供商配置扩展
PROVIDER_SPECIFIC_SCHEMA = {
	"anthropic": {
		"model_family": {
			"type": str,
			"required": False,
			"default": "claude",
			"description": "模型系列(Claude系列)"
		}
	},
	"openai": {
		"organization": {
			"type": str,
			"required": False,
			"description": "组织ID"
		}
	},
	"openrouter": {
		"app_name": {
			"type": str,
			"required": False,
			"default": "ConnLLM",
			"description": "应用名称(用于OpenRouter)"
		},
		"app_url": {
			"type": str,
			"required": False,
			"default": "https://github.com/your-username/ConnLLM",
			"description": "应用URL(用于OpenRouter)"
		},
		"transforms": {
			"type": list,
			"required": False,
			"description": "响应转换列表(用于OpenRouter)"
		}
	},
	"moonshot": {
		"search": {
			"type": bool,
			"required": False,
			"default": False,
			"description": "是否启用搜索功能(仅Moonshot支持)"
		}
	}
}

# 消息模式
MESSAGE_SCHEMA = {
	"role": {
		"type": str,
		"required": True,
		"allowed_values": ["system", "user", "assistant", "tool", "function"],
		"description": "消息角色"
	},
	"content": {
		"type": [str, list, None],  # 可以是字符串、列表(支持多模态)或None(当使用tool时)
		"required": True,
		"description": "消息内容"
	},
	"name": {
		"type": str,
		"required": False,
		"description": "可选的名称标识符"
	},
	"tool_calls": {
		"type": list,
		"required": False,
		"description": "工具调用列表(OpenAI格式)"
	},
	"tool_call_id": {
		"type": str,
		"required": False,
		"description": "工具调用ID(用于响应特定工具调用)"
	}
}


def validate_config(config: Dict[str, Any], schema: Dict[str, Dict[str, Any]]) -> Dict[str, Any]:
	"""
	验证配置是否符合模式，并应用默认值
	
	Args:
		config: 要验证的配置
		schema: 配置模式
		
	Returns:
		处理后的配置（包含默认值）
		
	Raises:
		ConfigurationError: 当配置不符合模式时
	"""
	errors = []
	result = config.copy()
	
	# 检查必填字段
	for field, field_schema in schema.items():
		if field_schema.get("required", False) and field not in config:
			errors.append(f"缺少必填字段: {field}")
		elif field not in config and "default" in field_schema:
			# 应用默认值
			result[field] = field_schema["default"]
	
	# 检查字段类型和允许值
	for field, value in config.items():
		if field in schema:
			field_schema = schema[field]
			expected_type = field_schema.get("type")
			
			# 支持多种类型
			if isinstance(expected_type, list):
				if not any(isinstance(value, t) for t in expected_type if t is not None) and value is not None:
					type_names = [t.__name__ if t is not None else "None" for t in expected_type]
					errors.append(f"字段 {field} 类型错误: 期望 {' 或 '.join(type_names)}, 实际 {type(value).__name__}")
			elif expected_type and not isinstance(value, expected_type) and value is not None:
				if expected_type == bool and isinstance(value, int) and (value == 0 or value == 1):
					# 允许将0/1转换为布尔值
					result[field] = bool(value)
				else:
					errors.append(f"字段 {field} 类型错误: 期望 {expected_type.__name__}, 实际 {type(value).__name__}")
			
			# 检查允许值
			allowed_values = field_schema.get("allowed_values")
			if allowed_values and value not in allowed_values:
				errors.append(f"字段 {field} 值错误: {value} 不在允许值列表中 {allowed_values}")
	
	if errors:
		raise ConfigurationError("\n".join(errors))
	
	return result


def get_provider_schema(provider_type: str) -> Dict[str, Dict[str, Any]]:
	"""
	获取指定提供商类型的配置模式
	
	Args:
		provider_type: 提供商类型
		
	Returns:
		合并后的配置模式
	"""
	from .constants import REMOTE_PROVIDERS, LOCAL_PROVIDERS
	
	# 基础模式
	schema = BASE_CONFIG_SCHEMA.copy()
	
	# 加载提供商类型特定模式
	if provider_type in REMOTE_PROVIDERS:
		# 合并远程提供商模式
		for key, value in REMOTE_CONFIG_SCHEMA.items():
			schema[key] = value
	elif provider_type in LOCAL_PROVIDERS:
		# 合并本地提供商模式
		for key, value in LOCAL_CONFIG_SCHEMA.items():
			schema[key] = value
	
	# 加载特定提供商模式
	if provider_type in PROVIDER_SPECIFIC_SCHEMA:
		specific_schema = PROVIDER_SPECIFIC_SCHEMA[provider_type]
		for key, value in specific_schema.items():
			schema[key] = value
	
	return schema


def validate_message(message: Dict[str, Any]) -> Dict[str, Any]:
	"""
	验证消息是否符合模式，并应用默认值
	
	Args:
		message: 要验证的消息
		
	Returns:
		处理后的消息（包含默认值）
		
	Raises:
		ValueError: 当消息不符合模式时
	"""
	try:
		return validate_config(message, MESSAGE_SCHEMA)
	except ConfigurationError as e:
		raise ValueError(f"消息格式错误: {str(e)}")


def validate_messages(messages: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
	"""
	验证消息列表是否符合模式，并应用默认值
	
	Args:
		messages: 要验证的消息列表
		
	Returns:
		处理后的消息列表（包含默认值）
		
	Raises:
		ValueError: 当消息不符合模式时
	"""
	if not isinstance(messages, list):
		raise ValueError(f"消息必须是列表, 实际为 {type(messages).__name__}")
	
	result = []
	for i, message in enumerate(messages):
		try:
			result.append(validate_message(message))
		except ValueError as e:
			raise ValueError(f"消息 #{i+1} 格式错误: {str(e)}")
	
	return result
